export default class Utils {

    public static getRandom(Min: number, Max: number): number {
        var Range = Max - Min;
        var Rand = Math.random();
        var num = Min + Math.round(Rand * Range); //四舍五入
        return num;
    }

    public static getRandomChoose<T>(list: T[]): T {
        if (list.length == 0) return null;
        return list[Utils.getRandom(0, list.length - 1)];
    }

    public static getRandomBoolean(probability: number = 0.5): boolean {
        return Math.random() < probability;
    }

    public static async getPrefabByPath(path: string): Promise<cc.Prefab> {
        return new Promise((resolve, reject) => {
            cc.resources.load(path, cc.Prefab, (err, ass) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(ass);
                }
            })
        })
    }

    public static angleToVectorCustom(angleInDegrees: number) {
        // 根据角度获取向量
        if (angleInDegrees < 90) {
            // 0度到89度，向量从 (0, 1) 逐渐过渡到 (-1, 0)
            let x = -Math.sin(cc.misc.degreesToRadians(angleInDegrees));
            let y = Math.cos(cc.misc.degreesToRadians(angleInDegrees));
            return cc.v3(x, y);
        } else if (angleInDegrees < 180) {
            // 90度到179度，向量从 (-1, 0) 到 (0, -1)
            angleInDegrees -= 90;
            let x = -Math.cos(cc.misc.degreesToRadians(angleInDegrees));
            let y = -Math.sin(cc.misc.degreesToRadians(angleInDegrees));
            return cc.v3(x, y);
        } else if (angleInDegrees < 270) {
            // 180度到269度，向量从 (0, -1) 到 (1, 0)
            angleInDegrees -= 180;
            let x = Math.sin(cc.misc.degreesToRadians(angleInDegrees));
            let y = -Math.cos(cc.misc.degreesToRadians(angleInDegrees));
            return cc.v3(x, y);
        } else {
            // 270度到359度，向量从 (1, 0) 到 (0, 1)
            angleInDegrees -= 270;
            let x = Math.cos(cc.misc.degreesToRadians(angleInDegrees));
            let y = Math.sin(cc.misc.degreesToRadians(angleInDegrees));
            return cc.v3(x, y);
        }
    }


    /**
     * 获取数组中最大数的位置
     * @param numbers 
     * @returns 
     */
    public static findMaxIndex(numbers: number[]): number {
        let maxIndex = 0;
        let maxValue = numbers[0];

        for (let i = 1; i < numbers.length; i++) {
            if (numbers[i] > maxValue) {
                maxValue = numbers[i];
                maxIndex = i;
            }
        }

        return maxIndex;
    }

    /**
     * 直接修改原数组
     * 数组原本长度>count，数组内容打乱后长度变成count
     * @param array 
     * @param count 
     * @returns 
     */
    public static shuffleArray<T>(array: T[], count: number = array.length): T[] {
        //洗牌 随机打乱
        for (let i = array.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [array[i], array[j]] = [array[j], array[i]];
        }
        if (array.length > count) {
            //限制长度
            array.slice(0, count);
        }
        return array;
    }

    /**
     * 按每个位置的概率获取随机索引
     * @param probabilityArray 每个位置存入的是这个位置的概率，必须大于0
     * @param totalProbability 总概率
     * @returns Index
     */
    public static getRandomIndexByProbability(probabilityArray: number[], totalProbability?: number): number {

        if (probabilityArray.findIndex(item => item == 0) >= 0) {
            cc.error("有0");
        }

        if (!totalProbability) {
            totalProbability = probabilityArray.reduce((acc, curr) => acc + curr, 0);
        }
        let randomValue = Utils.getRandom(0, totalProbability);
        let cumulativeSum = 0;
        const cumulativeArray = probabilityArray.map((number: number) => {
            cumulativeSum += number;
            return cumulativeSum;
        });
        let randomIndex = cumulativeArray.findIndex(number => randomValue <= number);
        return randomIndex;
    }


    /**
 * 检查是否在画面里
 * @param node 
 * @returns 
 */
    public static checkInView(node: cc.Node, camera: cc.Camera): boolean {
        if (node.isValid && camera.isValid) {
            let nodeBox = node.getBoundingBox();
            let screenBox = camera.node.getBoundingBox();
            screenBox.width *= 1.28;
            screenBox.height *= 1.28;
            // 检查节点的x坐标是否在屏幕的左右边界之内
            return cc.Intersection.rectRect(screenBox, nodeBox)
        }
        return false;
    }
}
